home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Games Collection 1
/
software vault.zip
/
software vault
/
CDR10
/
XLIB06.ZIP
/
XLIBTL02
/
XTSRTOOL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-22
|
17KB
|
571 lines
/*--------------------------------------------------------------------------*
| XTSRTOOL.C |
| contains main, interrupt handling, and DOS interface routines |
| for the XLIB TSR utility capture program. |
| WARNING: |
| STACK CHECKING MUST BE OFF AS WELL AS REGISTER VARIABLES DURING |
| COMPILATION. |
| Tsr code based on TC_TSR |
*--------------------------------------------------------------------------*/
#include <dos.h>
#include <conio.h>
#include <alloc.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dir.h>
#include "xtsrmous.h"
typedef unsigned char byte;
#define TRUE (1)
#define FALSE (0)
#define SAVE (0)
#define RESTORE (1)
#define ON (1)
#define OFF (0)
#define MIN_Y (0)
#define MIN_X (0)
#define MAX_Y (24)
#define MAX_X (79)
#define ALT (8)
#define SCAN_CODE_GRAB (55) /* the '*' key on the right keypad */
#define SCAN_CODE_CFG (29) /* the 'ctrl' key on the right keypad */
/* ie for configuration use Alt-Ctrl for grab use Alt-Kpd'*' */
#define INST_CODE_SET (0x5156) /* Uniqe id of BMP_GRAB */
#define INST_CODE_RET (0x5157) /* Unique return signature of BMP_GRAB */
#define cli() asm cli
#define sti() asm sti
void do_main_task(void);
void main_task(void);
#define CONFIG_MODE 0
#define GRAB_MODE 1
#define MEM_REQUIRED 950
#define COPY_PUT 0
#define BUFF_SIZE (64 * 48) /* size of the largest mosaic */
/* XTSRUTIL imports */
extern int get_video_mode(void);
extern void m13h_rect(int x, int y, int color);
extern void get_13h_rect(int x,int y, char *dest);
extern void put_13h_rect(int x,int y, char *src);
extern void get_line(int y, char *dest);
char bmsave[BUFF_SIZE];
char fname[100];
char path[80];
/*------------------------------------------------------------------------*
| GLOBAL VARIABLES |
*------------------------------------------------------------------------*/
void interrupt (* old_intr_0x09)(); /* pointer to old interrupt 0x9 */
void interrupt (* old_intr_0x28)(); /* pointer to old interrupt 0x28 */
void interrupt (* old_intr_0x11)(); /* pointer to old interrupt 0x11 */
unsigned far * EquipList=MK_FP(0x0000,0x0410); /* pointer to equip list */
unsigned _heaplen = 1; /* set minimum heap size */
unsigned c_ss, c_sp,c_psp; /* c_ss, c_sp are used to save stack */
unsigned save_ss, save_sp; /* save_ss and save_sp are used to save the */
/* active stack */
byte activation_mode; /* Determined by activation key */
int x=0,
y=0,
width=16,
height=16,
pwidth = 16,
pheight = 16,
color=16;
byte active = FALSE; /* program active flag (to prevent recursion) */
byte wanted = FALSE; /* wanted is set to TRUE if the Hot key was pressed */
/* but the program could not be activated */
byte far * dos_active; /* pointer to DOS busy flag */
byte far * shift_byte = (byte far *) 0x00400017L; /* pointer to keyboard */
/* status byte */
char capture_mode='L';
int lbm_count=0;
int pal_count=0;
int scr_count=0;
void build_name(){
switch (capture_mode) {
case 'L':sprintf(fname,"%sGRAB%04d.%s",path,lbm_count,"LBM"); break;
case 'P':sprintf(fname,"%sGRAB%04d.%s",path,pal_count,"PAL"); break;
case 'S':sprintf(fname,"%sGRAB%04d.%s",path,scr_count,"SCR"); break;
}
}
void error_buzz(){
/* Error Buzz - Can only capture while in mode 13x */
sound(100); delay(200); nosound();
}
void width_warning(){
if (width%4!=0){
printf("WARNING:The resulting LBM cannot be converted to a PBM\n");
printf(" The width is not a multiple of 4\n");
}
}
void configure(){
static firsttime=1;
unsigned mcbseg;
struct SREGS seg;
union REGS regs;
char ch;
int old_h=height,old_w=width;
int * work_count_ptr;
printf("Select mode\n P)alette L)BM S)creen");
if (!firsttime) printf(" R)eset-count Q)uit");
printf(": ");
do{
ch=toupper(getc(stdin));
} while(ch < ' ' || ch > 'Z');
switch (toupper(ch)) {
case 'L':
capture_mode='L';
printf("\nLinear Bitmap capture mode\n Width : ");
scanf("%d",&pwidth);
printf(" Height: ");
scanf("%d",&pheight);
printf(" Cursor Color: ");
scanf("%d",&color);
if(((long)width)*((long)height) > BUFF_SIZE) {
width=old_w;
height=old_h;
}
printf("\nSIZE= %dx%d cursor rect. color = %d\n",width,height,color);
build_name();
printf("Next output file is: '%s'\n",fname);
width_warning();
break;
case 'P':
capture_mode='P';
printf("\nPallete capture mode\n");
build_name();
printf("Next output file is: '%s'\n",fname);
break;
case 'S':
capture_mode='S';
printf("\nScreen capture mode\n");
build_name();
printf("Next output file is: '%s'\n",fname);
break;
case 'Q':
if (firsttime) break;
printf("\nQuitting XTSRTOOL. Bye...\n");
setvect( 0x09, old_intr_0x09 );
setvect( 0x28, old_intr_0x28 );
setvect( 0x11, old_intr_0x11 );
regs.h.ah=0x52;
intdos(®s,®s);
mcbseg=_ES;
mcbseg=peek(mcbseg,regs.x.bx-2);
segread(&seg);
while (peekb(mcbseg,0)==0x4D){
if (peek(mcbseg,1) == c_psp){
regs.h.ah=0x49;
seg.es=mcbseg+1;
intdosx(®s,®s,&seg);
}
mcbseg +=peek(mcbseg,3)+1;
}
exit(0);
break;
default: switch(capture_mode){
case 'L': printf("\nCurrently in LBM capture mode (%dx%d)\n",
width,height);
break;
case 'P': printf("\nCurrently in PALETTE capture mode\n");
break;
case 'S': printf("\nCurrently in SCREEN capture mode\n");
break;
};
if (toupper(ch)=='R'){
switch(capture_mode){
case 'L': work_count_ptr=&lbm_count;
break;
case 'P': work_count_ptr=&pal_count;
break;
case 'S': work_count_ptr=&pal_count;
break;
};
printf("\nCurrent File count = %d Enter new count:",*work_count_ptr);
scanf("%d",work_count_ptr);
}
build_name();
printf("Next output file is: '%s'\n",fname);
width_warning();
break;
}
firsttime=0;
}
void write_LBM(){
FILE *f;
int dummy;
int top, left;
width = pwidth;
height = pheight;
x=MouseX,y=MouseY;
HideMouse();
get_13h_rect(x,y,bmsave);
m13h_rect(MouseX,MouseY,color);
do{
MouseXY();
if (MouseX !=x || MouseY != y) {
put_13h_rect(x,y,bmsave);
x=MouseX,y=MouseY;
if (x+width>320) {
x=320-width;
MouseToXY(x,y);
}
if (y+height>200) {
y=200-height;
MouseToXY(x,y);
}
get_13h_rect(x,y,bmsave);
m13h_rect(x,y,color);
}
} while (!LeftPressed && !RightPressed);
/* find lower-right corner */
left = x;
top = y;
x = left + width;
y = top + height;
while (LeftPressed)
MouseXY();
MouseToXY(x, y);
if (!RightPressed) {
do {
MouseXY();
if (MouseX != x || MouseY != y) {
put_13h_rect(left,top,bmsave);
x = MouseX;
if (x - left < 2)
x = left + 2;
if (x - left > 63)
x = left + 63;
y = MouseY;
if (y - top < 2)
y = top + 2;
if (y - top > 47)
y = top + 47;
width = x - left;
height = y - top;
get_13h_rect(left,top,bmsave);
m13h_rect(left,top,color);
MouseToXY(x, y);
}
} while (!LeftPressed && !RightPressed);
}
if (LeftPressed) {
build_name();
if (f=fopen(fname,"wb")) {
if(!fwrite(bmsave,width*height+2,1,f)) {
fclose(f);
error_buzz();
} else {
fclose(f);
lbm_count++;
}
} else error_buzz();
}
MouseToXY(x - 1, y - 1);
while (LeftPressed)
MouseXY();
put_13h_rect(left,top,bmsave);
ShowMouse();
}
void write_SCR(){
FILE *f;
int i;
build_name();
if (f=fopen(fname,"wb")){
for (i=0;i<200;i++){
get_line(i,bmsave);
if(!fwrite(bmsave,320,1,f)) {
fclose(f);
error_buzz();
return;
}
}
fclose(f);
scr_count++;
} else error_buzz();
}
void write_PAL(){
FILE *f;
char far * scrn;
x_get_pal_raw(MK_FP(_DS,bmsave),256,0);
if (f=fopen(fname,"wb")){
if(!fwrite(bmsave,256*3,1,f)) {
fclose(f);
error_buzz();
} else {
fclose(f);
pal_count++;
}
} else error_buzz();
}
void main_task(void){
int video;
char ch;
video=get_video_mode();
if (activation_mode==CONFIG_MODE){
if (video==3){
printf("\n┌──────────────────────────────────────────────────────────────┐\n");
printf( "│XTSRTOOL - Mode 13x TSR screen/pallete/LBM capture utility │\n");
printf( "└──────────────────────────────────────────────────────────────┘\n\n");
configure();
} else {
/* Error Buzz - Can only configure while in text mode */
sound(100); delay(200); nosound();
}
} else {
if (video == 0x13) {
/* beep to let you know you're in grab mode */
sound(800); delay(70); nosound();
if (capture_mode=='L') write_LBM();
else if (capture_mode=='P') write_PAL();
else if (capture_mode=='S') write_SCR();
} else {
error_buzz();
}
}
};
void title_screen(){
clrscr();
printf("┌──────────────────────────────────────────────────────────────┐\n");
printf("│XTSRTOOL - Mode 13x TSR screen/pallete/LBM capture utility │\n");
printf("╞══════════════════════════════════════════════════════════════╡\n");
printf("│HOTKEYS: ALT-KPD'*' capture, ALT-CTRL configure │\n");
printf("│OUTPUT : GRABnnnn.LBM - xlib compatible linear bitmap mode │\n");
printf("│ GRABnnnn.PAL - xlib compatible raw palette mode │\n");
printf("│ GRABnnnn.SCR - raw screen dump │\n");
printf("└──────────────────────────────────────────────────────────────┘\n\n");
}
/*------------------------------------------------------------------------*
| Keyboard interrupt handler |
*------------------------------------------------------------------------*/
void kbd_reset(void){ /* Reset Keyboard and programable interrupt */
/* controller (PIC) */
register char x;
x = inp(0x61);
outportb(0x61, (x | 0x80));
outportb(0x61, x);
cli();
outportb(0x20, 0x20);
sti();
}/* kbd_reset */
int in_int08=0,int_09_stolen=0;
void interrupt intr_0x09(){ /* interrupt 9 handler (whenever a key is */
/* pressed control arrives hear) */
register char x;
sti();
x = inp(0x60); /* read keyboard data port */
if ( ( !active ) && /* if the program is not active and */
( x==SCAN_CODE_GRAB||
x==SCAN_CODE_CFG) && /* x == hot key scan code and */
( ((*shift_byte) & ALT) != 0) /* the ALT key is pressed */
)
{
activation_mode=(x==SCAN_CODE_GRAB);
active = TRUE; /* set active to prevent recursion */
kbd_reset(); /* reset keyboard controller and PIC */
if (!(*dos_active)){ /* if DOS is not active then do main task */
wanted = FALSE;
do_main_task();
}
else wanted = TRUE; /* else set wanted flag to be processed via */
/* interrupt 0x28 */
active = FALSE;
}
else {
(* old_intr_0x09)(); /* call old interrupt 9 handler */
}
} /* intr_0x09 */
/*------------------------------------------------------------------------*
| Interrupt 0x28 handler |
*------------------------------------------------------------------------*/
void interrupt intr_0x28(){
void interrupt (* curr_intr_0x09)();
(* old_intr_0x28)(); /* call old interrupt 0x28(to give other memory */
/* resident programs a chance to pop-up !) */
if (wanted){ /* if the wanted flag is set then do main task */
wanted = FALSE;
active = TRUE;
sti();
do_main_task();
cli();
active = FALSE;
} else {
}
} /* intr_0x28 */
/*------------------------------------------------------------------------*
| Interrupt 0x11 handler |
| Int11 : Is used normally by the system to retrieve the equipment list |
| word. We use it to determine if this TSR is already loaded; if CX |
| is equal to INST_CODE_SET, we set it to INST_CODE_RET, which is |
| then returned. Since CX is not used by Int11, and we load the |
| returned AX register with the equipment list word from low memory,|
| the operation should be transparent to other programs. |
*------------------------------------------------------------------------*/
void interrupt intr_0x11(unsigned bp, unsigned di, unsigned si,
unsigned ds, unsigned es, unsigned dx,
unsigned cx, unsigned bx, unsigned ax){
void interrupt (* curr_intr_0x11)();
(* old_intr_0x11)(); /* call old interrupt 0x28(to give other memory */
/* resident programs a chance to pop-up !) */
sti();
if (_CX==INST_CODE_SET) cx=INST_CODE_RET;
ax=*EquipList;
cli();
} /* intr_0x11 */
/*------------------------------------------------------------------------*
| do_main_task |
*------------------------------------------------------------------------*/
void do_main_task(void){
cli(); /* disable interrupts */
save_ss = _SS; save_sp = _SP; /* save the current stack */
_SS = c_ss; _SP = c_sp; /* restore XTSRTOOL's stack */
sti(); /* enable interrupts */
main_task();
cli(); /* disable interrupts */
_SS = save_ss; _SP = save_sp; /* restore stack */
sti(); /* enable interrupts */
} /* do_main_task() */
/*------------------------------------------------------------------------*
| get_dos_flag |
*------------------------------------------------------------------------*/
byte far * get_dos_flag(void){ /* get a pointer to DOS busy flag */
union REGS reg;
struct SREGS s_reg;
reg.x.ax = 0x3400; /* function 0x34 get DOS busy flag */
intdosx(®, ®, &s_reg); /* call DOS (interrupt 0x21) */
return( MK_FP(s_reg.es, reg.x.bx) ); /* return far pointer ES:BX */
}/* get_dos_flag() */
/*------------------------------------------------------------------------*
| program_size |
*------------------------------------------------------------------------*/
unsigned program_size(void){ /* return the size of the current memory */
/* control block (in paragraphs) */
return MEM_REQUIRED+(* ((unsigned far *) (MK_FP(_psp-1, 3))) ) ;
}/* program_size() */
/*------------------------------------------------------------------------*
| main function |
*------------------------------------------------------------------------*/
main(){
union REGS regs;
char ch;
c_ss = _SS; c_sp = _SP; /* save XTSRTOOL'S stack */
c_psp = _psp;
regs.x.cx = INST_CODE_SET;
int86(0x11,®s,®s);
if (regs.x.cx == INST_CODE_RET){
title_screen();
printf("\n XTSRTOOL already installed... \n ");
exit(0);
}
dos_active = get_dos_flag(); /* get a pointer to DOS busy flag */
old_intr_0x09 = getvect(0x09); /* save old interrupt 0x09 vector */
setvect( 0x09, intr_0x09 ); /* set interrupt 0x09 vector to 'intr_0x09' */
old_intr_0x28 = getvect(0x28); /* save old interrupt 0x28 vector */
setvect( 0x28, intr_0x28 ); /* set interrupt 0x28 vector to 'intr_0x28' */
old_intr_0x11 = getvect(0x11); /* save old interrupt 0x28 vector */
setvect( 0x11, intr_0x11 ); /* set interrupt 0x28 vector to 'intr_0x28' */
/* last */
strcpy(path,"X:\\");
path[0]='A'+getdisk();
getcurdir(0,path+3);
if (strlen(path)>3) strcat(path,"\\");
title_screen();
configure();
InitMouse();
HideMouse();
/* bug - sound usually doesnt work the first call so call it once */
sound(1);
delay(1);
nosound();
keep(0, (program_size())); /* terminate and stay resident */
} /* main() */